package cn.bluethink.eguan.core.service;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import cn.bluethink.eguan.core.entity.EgResultEntity;
import cn.bluethink.eguan.core.mapper.EgResultMapper;
import cn.bluethink.eguan.model.core.EgFile;
import cn.bluethink.eguan.model.core.EgOType;
import cn.bluethink.eguan.model.core.EgResult;
import cn.bluethink.eguan.utils.IdMakerUtils;
import tk.mybatis.mapper.entity.Example;

/**
 * 驿馆提交结果业务层
 * 
 * @author 苏州中科蓝迪公司所有(c)2016-2021
 * @version 0.3.0
 * @brief 驿馆+产品
 * @note 修订历史： 1.wanglei于2019/01/30设计并构建初始版本v0.3.0
 */
@Service
public class EgResultService {

    @Autowired
    private EgResultMapper resultMapper;

    @Autowired
    private EgFileService fileService;

    private IdMakerUtils idMakerUtil = new IdMakerUtils();

    /**
     * 创建结果
     * 
     * @param result
     * @return
     * @throws Exception
     */
    @Transactional(transactionManager = "eguanTransactionManager", rollbackFor = Exception.class)
    public EgResult create(EgResult result) throws Exception {
        result.setId(idMakerUtil.nextId());
        EgResultEntity entity = new EgResultEntity(result);
        int insertCount = resultMapper.insertSelective(entity);
        return insertCount > 0 ? entity.creatEgResult() : null;
    }

    /**
     * 根据提交的结果对象ID删除结果信息（包括提交的文件列表）
     * 
     * @param id
     * @param flag
     * @return
     * @throws Exception
     */
    @Transactional(transactionManager = "eguanTransactionManager", rollbackFor = Exception.class)
    public Boolean delete(Long id, Boolean flag) throws Exception {
        // 先查询结果对象实体
        EgResultEntity entity = resultMapper.selectByPrimaryKey(id);
        if (entity == null) {
            return null;
        }
        if (flag) {
            // 获取提交的文件标识列表
            String files = entity.getFiles();
            List<Long> fileIds = new ArrayList<>();
            if (StringUtils.isNotBlank(files)) {
                String[] fileStrIds = files.split(",");
                for (String fileId : fileStrIds) {
                    fileIds.add(Long.valueOf(fileId));
                }
            }
            // 如果结果对象包含了文件，先删除提交的文件
            if (fileIds != null && fileIds.size() > 0) {
                if (!fileService.delByIds(fileIds)) {
                    throw new RuntimeException("删除结果失败，请重试！");
                }
            }
        }
        // 删除提交的结果
        int delCount = resultMapper.deleteByPrimaryKey(id);
        return delCount > 0 ? true : false;
    }

    /**
     * 更新结果对象（两种情况）
     * 
     * @param result
     * @param flag
     * @return
     * @throws Exception
     */
    @Transactional(transactionManager = "eguanTransactionManager", rollbackFor = Exception.class)
    public EgResult update(EgResult result, Boolean flag) throws Exception {
        EgResultEntity entity = new EgResultEntity(result);
        int updateCount = 0;
        if (flag) {
            // 根据主键更新属性不为null的值
            updateCount = resultMapper.updateByPrimaryKeySelective(entity);
        } else {
            // 根据主键更新实体全部字段，null值会被更新
            updateCount = resultMapper.updateByPrimaryKey(entity);
        }
        return updateCount > 0 ? entity.creatEgResult() : null;
    }

    /**
     * 根据结果主键Id获取结果详情（结果描述以及文件列表详情）
     * 
     * @param id
     * @return
     * @throws Exception
     */
    public EgResult detail(Long id) throws Exception {
        EgResultEntity entity = resultMapper.selectByPrimaryKey(id);
        if (entity == null) {
            return null;
        }
        EgResult result = entity.creatEgResult();
        // 获取文件列表
        List<EgFile> fileList = result.getFileList();
        List<Long> fileIds = new ArrayList<>();
        if (fileList != null && fileList.size() > 0) {
            fileIds = fileList.stream().map(f -> f.getId()).collect(Collectors.toList());
        }
        if (fileIds != null && fileIds.size() > 0) {
            // 加载文件列表的详情
            fileList = fileService.queryByFileIds(fileIds);
            result.setFileList(fileList);
        }
        return result;
    }

    /**
     * 
     * 根据某对象及其对象类型，操作者查询提交的结果列表
     * 
     * @param oid
     * @param otype
     * @param uids
     * @return
     * @throws Exception
     */
    public List<EgResult> query(Long oid, Integer otype, List<Long> uids) throws Exception {
        Example example = new Example(EgResultEntity.class);
        example.and().andEqualTo("oid", oid).andEqualTo("otype", otype).andIn("uid", uids);
        // 查询所有的结果列表
        List<EgResultEntity> entities = resultMapper.selectByExample(example);
        Map<Long, EgResult> resultMap = new HashMap<>();
        if (entities != null && entities.size() > 0) {
            entities.forEach(e -> {
                try {
                    resultMap.put(e.getUid(), e.creatEgResult());
                } catch (Exception e1) {
                    e1.printStackTrace();
                }
            });
        }
        // 获取所有的提交的文件列表
        List<EgFile> fileList = fileService.queryByUploaders(oid, EgOType.REWARD_TASK, uids);
        Map<Long, List<EgFile>> fileMap = new HashMap<>();
        if (fileList != null && fileList.size() > 0) {
            uids.forEach(uId -> {
                fileMap.put(uId, fileList.stream().filter(f -> f.getUploader().getId().equals(uId))
                        .collect(Collectors.toList()));
            });
        }
        // 定义返回的结果列表
        List<EgResult> results = new ArrayList<>();
        List<EgFile> files = new ArrayList<>();
        for (Long uid : uids) {
            if (fileMap != null && fileMap.size() > 0) {
                files = fileMap.get(uid);
            }
            if (resultMap != null && resultMap.size() > 0) {
                EgResult result = resultMap.get(uid);
                if (result == null)
                    break;
                result.setFileList(files);
                results.add(result);
            }
        }
        return results;
    }
}
